package cn.dogger.easyboot.init.handler;

import cn.dogger.easyboot.common.exception.InitTableException;
import cn.dogger.easyboot.init.annotation.InitField;
import cn.dogger.easyboot.init.annotation.InitTable;
import cn.dogger.easyboot.init.domain.FieldsEntity;
import cn.dogger.easyboot.init.domain.TableEntity;
import cn.dogger.easyboot.init.enums.FieldTypeEnums;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 字段处理类
 *
 * @author dogger
 * 2022-07-20 15:13
 */
public class FieldHandler {
    private final static String  DECIMAL_POINT = ".";
    private final static String INIT_PACKAGE = "cn.dogger.easyboot.init.initEntity";
    /**
     * 获取生成表的类下的注解的值
     *
     * @return 集合
     */
    public static List<TableEntity> getEntityAnnotationValues() {
        try {
            // 获取包名下所有类
            Set<Class<?>> classes = ClassHandler.getClasses(INIT_PACKAGE);
            List<TableEntity> tableEntities = new ArrayList<>();
            for (Class c : classes) {
                TableEntity tableEntity = new TableEntity();
                //获取类的注解
                InitTable tableAnnotation = (InitTable) c.getAnnotation(InitTable.class);
                if (tableAnnotation ==null){
                    throw new InitTableException(c.getName()+"缺少注解InitTable");
                }
                //表名
                tableEntity.setName(tableAnnotation.name());
                //表注释
                tableEntity.setRemark(tableAnnotation.remark());
                //获取字段注解
                List<FieldsEntity> fieldsEntities = new ArrayList<>();
                Field[] fields = c.getDeclaredFields();
                for (Field field : fields) {
                    FieldsEntity fieldsEntity = new FieldsEntity();
                    //每个字段的注解
                    InitField fieldAnnotation = field.getAnnotation(InitField.class);
                    if (fieldAnnotation ==null){
                        throw new InitTableException(c.getName()+"缺少注解InitField");
                    }
                    fieldsEntity.setDecimalPoint(fieldAnnotation.decimalPoint())
                            .setKeyFlag(fieldAnnotation.keyFlag())
                            .setAllowNull(fieldAnnotation.allowNull())
                            .setRemark(fieldAnnotation.remark())
                            .setDefaultValue(fieldAnnotation.defaultValue())
                            .setFieldLength(fieldAnnotation.fieldLength())
                            .setName(fieldAnnotation.name())
                            .setType(FieldTypeEnums.getValue(fieldAnnotation.type()))
                            .setTypeEnums(fieldAnnotation.type())
                            .setDecimalPoint(fieldAnnotation.decimalPoint());
                    fieldsEntities.add(fieldsEntity);
                }
                tableEntity.setFieldsEntities(fieldsEntities);
                tableEntities.add(tableEntity);
            }
            return tableEntities;
        } catch (Exception e) {
            throw new InitTableException(e);
        }
    }

    /**
     * 获取默认长度,
     * 只有必须有长度的字段且用户未填该字段长度时获取
     *
     * @param entity 实体
     * @return 实体
     */
    public static FieldsEntity getDefaultLength(FieldsEntity entity) {
        if (entity.getTypeEnums() == FieldTypeEnums.int_) {
            entity.setFieldLength(Math.min(entity.getFieldLength(), Integer.MAX_VALUE));
            //如果没有填长度,就获取默认长度
            entity.setFieldLength(entity.getFieldLength() == -1 ? FieldTypeEnums.int_.getFieldLength() : entity.getFieldLength());
        } else if (entity.getTypeEnums() == FieldTypeEnums.varchar_) {
            //如果没有填长度,就获取默认长度
            entity.setFieldLength(entity.getFieldLength() == -1 ? FieldTypeEnums.varchar_.getFieldLength() : entity.getFieldLength());
        } else if (entity.getTypeEnums() == FieldTypeEnums.decimal_) {
            //如果没有填长度,就获取默认长度和小数点后位数
            entity.setFieldLength(entity.getFieldLength() == -1 ? FieldTypeEnums.decimal_.getFieldLength() : entity.getFieldLength());
            entity.setDecimalPoint(entity.getDecimalPoint() == -1 ? FieldTypeEnums.decimal_.getDecimalPoint() : entity.getDecimalPoint());
        } else if (entity.getTypeEnums() == FieldTypeEnums.char_) {
            //如果没有填长度,就获取默认长度
            entity.setFieldLength(entity.getFieldLength() == -1 ? FieldTypeEnums.char_.getFieldLength() : entity.getFieldLength());
        } else if (entity.getTypeEnums() == FieldTypeEnums.date_) {
            //date类型不能有长度
            entity.setFieldLength(-1).setDecimalPoint(-1);
        } else if (entity.getTypeEnums() == FieldTypeEnums.datetime_) {
            //date类型不能有长度
            entity.setFieldLength(-1).setDecimalPoint(-1);
        }
        //后续需要校验其它类型的输入值是否符合长度就 else if
        return entity;
    }

    /**
     * 校验默认值
     *
     * @param entity 实体
     * @return 实体
     */
    public static FieldsEntity verifyDefault(FieldsEntity entity) {
        try {
            if (entity.getTypeEnums() == FieldTypeEnums.int_ && StringUtils.isNotBlank(entity.getDefaultValue())) {
                Integer.parseInt(entity.getDefaultValue());
                if(entity.getDefaultValue().length()>entity.getFieldLength()){
                    throw new RuntimeException();
                }
            } else if (entity.getTypeEnums() == FieldTypeEnums.decimal_) {
                //默认值是否是float类型
                Float.parseFloat(entity.getDefaultValue());
                if(entity.getDefaultValue().indexOf(DECIMAL_POINT)+1 > entity.getDecimalPoint()){
                    //小数点后是否符合标准
                    throw new RuntimeException();
                }else if (entity.getDefaultValue().substring(0,entity.getDefaultValue().indexOf(DECIMAL_POINT)).length() > entity.getFieldLength()){
                    //整数部分长度
                    throw new RuntimeException();
                }
                //后续需要校验默认值就继续添加 else if
            }
        } catch (RuntimeException e) {
            throw new InitTableException("默认值与类型不符! ");
        }
        return entity;
    }

    /**
     * 合理化sql语句
     * 例如 主键就自动不能为空 之类的
     * @return 实体
     */
    public static TableEntity rationalizationSql(TableEntity tableEntity){
        //字段集合
        List<FieldsEntity> fieldsEntities = tableEntity.getFieldsEntities();
        fieldsEntities.forEach(fields->{
            fields = getDefaultLength(fields);
            fields = verifyDefault(fields);
            if(fields.isKeyFlag()){
                //主键字段  `field`
                String key = "`"+fields.getName()+"`";
                tableEntity.setFieldKeys(StringUtils.isBlank(tableEntity.getFieldKeys())?key:tableEntity.getFieldKeys()+","+key);
                //主键字段不能为空
                fields.setAllowNull(false);
            }
        });
        return tableEntity;
    }
}
